package Model

import "time"

type Employee struct {
	//首字母小写即为private类型，其他包不能直接访问
	itsEmpid          int
	itsName           string
	itsAddress        string
	itsClassification PaymentClassification //支付类别
	itsSchedule       PaymentSchedule       //支付时间
	itsPaymentMethod  PaymentMethod         //支付方式
	itsAffiliation    Affiliation           //从属关系
}

//初始化函数
//可能需要换为工厂模式
// func (e *Employee) Employee(empid int, name string, address string) {
// 	e.itsEmpid = empid
// 	e.itsName = name
// 	e.itsAddress = address
// 	e.itsAffiliation = &NoAffiliation{}
// }

//工厂模式如下,相当于构造函数,需要用set和get访问private变量
func NewEmployee(empid int, name string, address string) *Employee {
	return &Employee{
		itsEmpid:       empid,
		itsName:        name,
		itsAddress:     address,
		itsAffiliation: &NoAffiliation{},
	}
}

//set方法
func (e *Employee) SetClassification(pc PaymentClassification) {
	e.itsClassification = pc
}
func (e *Employee) SetSchedule(ps PaymentSchedule) {
	e.itsSchedule = ps
}
func (e *Employee) SetMethod(pm PaymentMethod) {
	e.itsPaymentMethod = pm
}
func (e *Employee) SetAffiliation(af Affiliation) {
	e.itsAffiliation = af
}
func (e *Employee) SetName(name string) {
	e.itsName = name
}
func (e *Employee) SetAddress(address string) {
	e.itsAddress = address
}

//get方法
func (e *Employee) GetName() string {
	return e.itsName
}
func (e *Employee) GetClassification() PaymentClassification {
	return e.itsClassification
}
func (e *Employee) GetSchedule() PaymentSchedule {
	return e.itsSchedule
}
func (e *Employee) GetAffiliation() Affiliation {
	return e.itsAffiliation
}
func (e *Employee) GetEmpid() int {
	return e.itsEmpid
}
func (e *Employee) GetAddress() string {
	return e.itsAddress
}

//特殊函数
//判断是否为发薪日期
func (e *Employee) IsPayDate(payDate time.Time) bool {
	return e.itsSchedule.IsPayDate(payDate)
}

//获取开始到结束天数
func (e *Employee) GetPayPeriodStartDate(payPeriodEndDate time.Time) time.Time {
	return e.itsSchedule.GetPayPeriodStartDate(payPeriodEndDate)
}

//支付
func (e *Employee) Payday(pc Paycheck) {
	grossPay := e.itsClassification.CalculatePay(pc)
	deductions := e.itsAffiliation.CalculateDeductions(pc)
	netPay := grossPay - deductions
	pc.SetGrossPay(grossPay)
	pc.SetDeductions(deductions)
	pc.SetNetPay(netPay)
	e.itsPaymentMethod.Pay(pc)
}
